package designpatterns.structure;

/**
 * 装饰器模式
 * 装饰器模式和代理模式区别：装饰器模式关注于在一个对象上动态的添加方法，然而代理模式关注于控制对对象的访问
 * 分为核心角色和装饰器角色
 * 指在不改变现有对象结构的情况下，动态地给该对象增加一些职责
 * 使用场景：在软件开发过程中，有时想用一些现存的组件。
 * 这些组件可能只是完成了一些核心功能。但在不改变其结构的情况下，可以动态地扩展其功能
 * 优点：1、采用装饰模式扩展对象的功能比采用继承方式更加灵活
 * 2、可以设计出多个不同的具体装饰类，创造出多个不同行为的组合
 * 缺点：装饰模式增加了许多子类，如果过度使用会使程序变得很复杂。
 *
 * @author jack.wu
 * @since 2019/9/21
 */
public class DecoratorTest {

    public static void main(String[] args) {
        Shape circle = new Circle1();
        RedShapeDecorator redShapeDecorator = new RedShapeDecorator(circle);
        circle.draw();
        System.out.println();
        redShapeDecorator.draw();
    }
}

interface Shape {
    void draw();
}

class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Shape: Rectangle");
    }
}

class Circle1 implements Shape {
    @Override
    public void draw() {
        System.out.println("Shape: Circle");
    }
}

abstract class AbstractShapeDecorator implements Shape {

    public Shape decoratorShape;

    public AbstractShapeDecorator(Shape decoratorShape) {
        this.decoratorShape = decoratorShape;
    }

    @Override
    public void draw(){
        decoratorShape.draw();
    }
}

class RedShapeDecorator extends AbstractShapeDecorator{

    public RedShapeDecorator(Shape decoratorShape) {
        super(decoratorShape);
    }

    @Override
    public void draw() {
        decoratorShape.draw();
        setRedBorder(decoratorShape);
    }

    private void setRedBorder(Shape decoratorShape) {
        System.out.println("Border Color: Red");
    }
}


